//
//  JCCNetworking.m
//  test
//
//  Created by jcc on 16/7/1.
//  Copyright © 2016年 jcc. All rights reserved.
//

#import "JCCNetworking.h"
#import <AFNetworking.h>
#import "AFNetworkActivityIndicatorManager.h"
#import "AFHTTPSessionManager.h"

static NSString *AFNetworkingBaseUrl = nil;
static JCCNetworking *jcc_instance = nil;
static BOOL jcc_isBaseURLChanged = YES;
static AFHTTPSessionManager *jcc_sharedManager = nil;
static NSTimeInterval jcc_timeout = 60.0f;

@interface JCCNetworking ()

@end
@implementation JCCNetworking

+ (JCCNetworking *)shareInstance{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        jcc_instance = [[JCCNetworking alloc] init];
    });
    return jcc_instance;
}

+ (void)setBaseUrl:(NSString *)baseUrl{
    if ([baseUrl isEqualToString:AFNetworkingBaseUrl] && baseUrl && baseUrl.length) {
        jcc_isBaseURLChanged = YES;
    } else {
        jcc_isBaseURLChanged = NO;
    }

    AFNetworkingBaseUrl = baseUrl;
}

+ (NSString *)baseUrl{
    return AFNetworkingBaseUrl;
}

+ (void)setTimeout:(NSTimeInterval)timeout {
    jcc_timeout = timeout;
}

+ (JCCURLSessionTask *)postWithUrl:(NSString *)url
                            params:(NSDictionary *)params
                           success:(JCCResponseSuccess)success
                              fail:(JCCResponseFail)fail{
    AFHTTPSessionManager *manager = [self manager];
    JCCURLSessionTask *session = nil;
  session = [manager POST:url parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self successResponse:responseObject callback:success];
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self handleCallbackWithError:error fail:fail];
    }];
    return session;
}

+ (JCCURLSessionTask *)getWithUrl:(NSString *)url params:(NSDictionary *)params success:(JCCResponseSuccess)success fail:(JCCResponseFail)fail{
    AFHTTPSessionManager *manager = [self manager];
    JCCURLSessionTask *session = nil;
    session = [manager GET:url parameters:params progress:^(NSProgress * _Nonnull downloadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [self successResponse:responseObject callback:success];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [self handleCallbackWithError:error fail:fail];
    }];
    return session;
}

+ (JCCURLSessionTask *)downLoadUrl:(NSString *)url savePath:(NSString *)path progress:(JCCDownloadProgress)progressBlock success:(JCCResponseSuccess)success failure:(JCCResponseFail)failure{
    if ([self baseUrl] == nil) {
        if ([NSURL URLWithString:url] == nil) {
            return nil;
        }
    } else {
        if ([NSURL URLWithString:[NSString stringWithFormat:@"%@%@", [self baseUrl], url]] == nil) {
            return nil;
        }
    }
    
    NSURLRequest *downloadRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    AFHTTPSessionManager *manager = [self manager];
    
    JCCURLSessionTask *session = nil;
    session = [manager downloadTaskWithRequest:downloadRequest progress:^(NSProgress * _Nonnull downloadProgress) {
        if (progressBlock) {
            progressBlock(downloadProgress.completedUnitCount,downloadProgress.totalUnitCount);
        }
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        return [NSURL fileURLWithPath:path];
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        if (error == nil) {
            if (success) {
                success(filePath.absoluteString);
            }
        }
    }];
    [session resume];
    
    return session;
}
+ (void)successResponse:(id)responseData callback:(JCCResponseSuccess)success {
    if (success) {
        success([self tryToParseData:responseData]);
    }
}

+ (void)handleCallbackWithError:(NSError *)error fail:(JCCResponseFail)fail {
    if (fail) {
        fail(error);
    }
}
+ (id)tryToParseData:(id)responseData {
    if ([responseData isKindOfClass:[NSData class]]) {
        // 尝试解析成JSON
        if (responseData == nil) {
            return responseData;
        } else {
            NSError *error = nil;
            NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseData
                                                                     options:NSJSONReadingMutableContainers
                                                                       error:&error];
            if (error != nil) {
                return responseData;
            } else {
                return response;
            }
        }
    } else if ([responseData isKindOfClass:[NSDictionary class]]){
        NSDictionary *dic = [[NSDictionary alloc] initWithDictionary:responseData copyItems:YES];
        
        return dic;
    }else{
        return responseData;
    }
}
+ (AFHTTPSessionManager *)manager{
    // 只要不切换baseurl，就一直使用同一个session manager
    if (jcc_sharedManager == nil || jcc_isBaseURLChanged) {
        // 开启转圈圈
        [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
        
        AFHTTPSessionManager *manager = nil;;
        if ([self baseUrl] != nil) {
            manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:[self baseUrl]]];
        } else {
            manager = [AFHTTPSessionManager manager];
        }
        //设置接收格式
        manager.responseSerializer.acceptableContentTypes = [NSSet setWithArray:@[@"application/json",
                           @"text/html",
                           @"text/json",
                           @"text/plain",
                           @"text/javascript",
                           @"text/xml",
                           @"image/*"]];
        //设置网络超时时间
        manager.requestSerializer.timeoutInterval = jcc_timeout;
        
        // 设置允许同时最大并发数量，过大容易出问题
        manager.operationQueue.maxConcurrentOperationCount = 3;
        jcc_sharedManager = manager;
        
    }
    return jcc_sharedManager;
}



@end
